[IA64] Fix time_resume()
authorAlex Williamson <alex.williamson@hp.com>
Thu, 3 May 2007 20:21:39 +0000 (14:21 -0600)
committerAlex Williamson <alex.williamson@hp.com>
Thu, 3 May 2007 20:21:39 +0000 (14:21 -0600)
Add missing exclusion in time_resume() and steal time accounting
reinitialization after resume.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
linux-2.6-xen-sparse/arch/ia64/kernel/time.c
linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c

index e9d72d89a34c8559bad0f60bbac02b76e324227c..a151b72a210271d0d4ddb3dcd7e06ffb588ceb6c 100644 (file)
@@ -267,6 +267,62 @@ static void init_missing_ticks_accounting(int cpu)
        per_cpu(processed_stolen_time, cpu) = runstate->time[RUNSTATE_runnable]
                                            + runstate->time[RUNSTATE_offline];
 }
+
+static int xen_ia64_settimefoday_after_resume;
+
+static int __init __xen_ia64_settimeofday_after_resume(char *str)
+{
+       xen_ia64_settimefoday_after_resume = 1;
+       return 1;
+}
+
+__setup("xen_ia64_settimefoday_after_resume",
+        __xen_ia64_settimeofday_after_resume);
+
+/* Called after suspend, to resume time.  */
+void
+time_resume(void)
+{
+       unsigned int cpu;
+       
+       /* Just trigger a tick.  */
+       ia64_cpu_local_tick();
+
+       if (xen_ia64_settimefoday_after_resume) {
+               /* do_settimeofday() resets timer interplator */
+               struct timespec xen_time;
+               int ret;
+               efi_gettimeofday(&xen_time);
+
+               ret = do_settimeofday(&xen_time);
+               WARN_ON(ret);
+       } else {
+#if 0
+               /* adjust EFI time */
+               struct timespec my_time = CURRENT_TIME;
+               struct timespec xen_time;
+               static timespec diff;
+               struct xen_domctl domctl;
+               int ret;
+
+               efi_gettimeofday(&xen_time);
+               diff = timespec_sub(&xen_time, &my_time);
+               domctl.cmd = XEN_DOMCTL_settimeoffset;
+               domctl.domain = DOMID_SELF;
+               domctl.u.settimeoffset.timeoffset_seconds = diff.tv_sec;
+               ret = HYPERVISOR_domctl_op(&domctl);
+               WARN_ON(ret);
+#endif
+               /* Time interpolator remembers the last timer status.
+                  Forget it */
+               write_seqlock_irq(&xtime_lock);
+               time_interpolator_reset();
+               write_sequnlock_irq(&xtime_lock);
+       }
+
+       for_each_online_cpu(cpu)
+               init_missing_ticks_accounting(cpu);
+}
 #else
 #define init_missing_ticks_accounting(cpu) do {} while (0)
 #endif
index cb7885dfd3e4b41f9d33bdbdddbf7cd982706850..0b84bcfa9c2d665f26cffb0e4b57ab962997cb9d 100644 (file)
@@ -863,19 +863,6 @@ direct_remap_pfn_range(struct vm_area_struct *vma,
 }
 
 
-/* Called after suspend, to resume time.  */
-void
-time_resume(void)
-{
-       extern void ia64_cpu_local_tick(void);
-
-       /* Just trigger a tick.  */
-       ia64_cpu_local_tick();
-
-       /* Time interpolator remembers the last timer status.  Forget it */
-       time_interpolator_reset();
-}
-
 ///////////////////////////////////////////////////////////////////////////
 // expose p2m table
 #ifdef CONFIG_XEN_IA64_EXPOSE_P2M